﻿using System;
using System.CodeDom;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Resources;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace HaumDisplay
{
    /// <summary>
    /// HaumDisplayWindow图像显示控件
    /// </summary>
    public partial class HaumDisplayWindow : UserControl
    {

        #region 图像基础操作
        /// <summary>
        /// 显示图像
        /// </summary>
        public HaumImage image;

        /// <summary>
        /// 图像锁
        /// </summary>
        private object bmpLock = new object();

        /// <summary>
        /// 图像角度
        /// </summary>
        public float imageAngle;

        /// <summary>
        /// 缩放比例
        /// </summary>
        private float scaleF = 1.0f;

        /// <summary>
        /// 开始移动时鼠标位置
        /// </summary>
        private Point startMovePosition = Point.Empty;

        /// <summary>
        /// 当前图像基于原图偏移量
        /// </summary>
        private PointF offset = Point.Empty;

        /// <summary>
        /// 图像显示模式 ： 高质量（平滑处理锯齿不失真）， 像素级（能够清晰显示每一个像素，锯齿边缘明显，适合查看像素坐标与rgb值）
        /// </summary>
        private HAUM_DISPALY_MODE viewMode = HAUM_DISPALY_MODE.Pixel;

        #endregion

        #region 图形绘制操作
        /// <summary>
        /// 操作模式：记录操作模式或当前绘制图型类型
        /// </summary>
        private HAUM_DRAW_MODE operatorMode = HAUM_DRAW_MODE.None;

        /// <summary>
        /// 绘制状态标志位
        /// </summary>
        private HAUM_DRAW_STATUS operatorStatus = HAUM_DRAW_STATUS.Done;

        /// <summary>
        /// 画笔粗细
        /// </summary>
        private int penSize = 1;

        /// <summary>
        /// 画笔颜色
        /// </summary>
        private Color penColor = Color.Green;

        /// <summary>
        /// 绘制点对象
        /// </summary>
        private HaumPoint haumPoint;
        /// <summary>
        /// 绘制线对象
        /// </summary>
        private HaumLine haumLine;
        /// <summary>
        /// 绘制矩形对象
        /// </summary>
        private HaumRectangle haumRectangle;
        /// <summary>
        /// 绘制椭圆
        /// </summary>
        private HaumEllipse haumEllipse;
        /// <summary>
        /// 绘制圆对象
        /// </summary>
        private HaumCircle haumCircle;
        /// <summary>
        /// 绘制多边形对象
        /// </summary>
        private HaumPolygon haumPolygon;
        /// <summary>
        /// 绘制可旋转矩形
        /// </summary>
        private HaumRotateRect haumRotateRect;
        /// <summary>
        /// 旋转光标
        /// </summary>
        private Cursor rotateCursor;

        #endregion

        #region 像素与坐标信息
        /// <summary>
        /// 显示像素信息控件
        /// </summary>
        private HaumPixelInfo pixelInfo = new HaumPixelInfo();

        /// <summary>
        /// 是否位于显示上方
        /// </summary>
        private bool isInView;

        /// <summary>
        /// 当前鼠标相对于mainView的坐标点
        /// </summary>
        private Point mousePoint = new Point();

        /// <summary>
        /// 监听快捷键线程
        /// </summary>
        private Thread listenKeys;
        #endregion

        #region 图像属性信息
        /// <summary>
        /// 信息窗口
        /// </summary>
        private HaumImageInfo imageInfo;

        #endregion

        #region 控件风格

        [Category("WindowStyle")]//(属性类)
        [Description("导航栏背景颜色")]// 
        public Color BarBackColor {
            get { return toolStrip_menu.BackColor; }
            set { toolStrip_menu.BackColor = value; }
        }

        [Category("WindowStyle")]//(属性类)
        [Description("导航栏前景颜色")]// 
        public Color BarForeColor {
            get { return toolStrip_menu.ForeColor; }
            set { toolStrip_menu.ForeColor = value; }
        }

        [Category("WindowStyle")]//(属性类)
        [Description("显示窗口颜色")]// 
        public Color WindowColor {
            get { return mainView.BackColor; }
            set { mainView.BackColor = value; }
        }


        #endregion


        /// <summary>
        /// 初始化控件
        /// </summary>
        public HaumDisplayWindow()
        {
            InitializeComponent();
            //绑定显示控件鼠标滑动事件 进行缩放
            mainView.MouseWheel += mainView_MouseWheel;
            // 启用控件双缓冲 防止控件重绘闪烁
            this.DoubleBuffered = true;
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
            //初始化旋转弧形鼠标样式
            // 加载自定义光标文件，这里假设你有一个名为 custom_cursor.cur 的光标文件在项目目录下
            using (MemoryStream ms = new MemoryStream(Properties.Resources.弧线))
            {
                rotateCursor = new Cursor(ms);
            }
        }

        /// <summary>
        /// 监听快捷键
        /// </summary>
        private void ListenKeys()
        {
            while (this.Created)
            {
                lock (bmpLock)
                {
                    PointF imagePoint = ScreenTransImagePointF(mousePoint);

                    if (Control.ModifierKeys == Keys.Control && image != null && IsMouseInImage(imagePoint, image.bmp.Size) && isInView)
                    {
                        Point xy = new Point((int)imagePoint.X, (int)imagePoint.Y);
                        Color rgb = image.bmp.GetPixel(xy.X, xy.Y);
                        //显示提示
                        this.BeginInvoke(new Action(delegate
                        {
                            pixelInfo.Visible = true;
                            pixelInfo.SetPixelInfo(xy, rgb, new Point(Control.MousePosition.X + 10, Control.MousePosition.Y + 15));
                        }));
                    }

                    else
                    {
                        this.BeginInvoke(new Action(delegate
                        {
                            pixelInfo.Visible = false;
                        }));
                    }
                }
                Thread.Sleep(10);
            }
        }

        /// <summary>
        /// 判断鼠标位置是否在图像宽高范围内
        /// </summary>
        /// <param name="point"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        private bool IsMouseInImage(PointF point, Size size)
        {
            if (point.X >= 0 && point.X < size.Width && point.Y >= 0 && point.Y < size.Height)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 显示图片
        /// </summary>
        /// <param name="image">图片</param>
        public void ShowImage(Image image)
        {
            this.ClearDraw();
            try
            {
                this.image = new HaumImage(image);
            }
            catch (Exception ex) {
                MessageBox.Show("创建图片对象异常");
            }
            this.Fit();
        }


        /// <summary>
        /// 图像自适应
        /// </summary>
        public void Fit()
        {
            if (image == null) { return; }
            //计算控件与图像的宽高比例
            float scaleX = (float)(mainView.Width - 2) / image.bmp.Width;
            float scaleY = (float)(mainView.Height - 2) / image.bmp.Height;
            //获取较小的一边比例作为缩放比例
            scaleF = Math.Min(scaleX, scaleY);

            //计算缩放后的图像宽高值
            int newWidth = (int)(image.bmp.Width * scaleF);
            int newHeight = (int)(image.bmp.Height * scaleF);

            //计算图像居中显示的位置
            offset.X = (mainView.Width - newWidth) / 2;
            offset.Y = (mainView.Height - newHeight) / 2;

            //触发自身的Point方法进行控件重绘
            mainView.Invalidate();
        }

        /// <summary>
        /// 导入图片
        /// </summary>
        public void ImportImage()
        {
            //打开文件对话框进行选择图片并触发显示控件重绘
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.Filter = "图像文件(*.bmp;*.png;*.jpg;*.jpeg;*.tiff;*.gif)|*.bmp;*.png;*.jpg;*.jpeg;*.tiff;*.gif|所有文件(*.*)|*.*";
                ofd.Title = "选择导入并显示图片";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    this.ClearDraw();
                    try
                    {
                        Image image = Image.FromFile(ofd.FileName);
                        this.image = new HaumImage(image, ofd.FileName);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("加载失败，可能的原因是：文件已损坏。");
                    }
                    this.Fit();
                }
            }
        }

        /// <summary>
        /// 根据路径加载图片
        /// </summary>
        /// <param name="path">图片文件路径</param>
        public void LoadImage(string path)
        {
            if (File.Exists(path))
            {
                this.ClearDraw();
                try
                {
                    Image image = Image.FromFile(path);
                    this.image = new HaumImage(image, path);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("加载失败，可能的原因是：文件已损坏。");
                }
                this.Fit();
            }
        }

        /// <summary>
        /// 移除图片
        /// </summary>
        public void RemoveImage()
        {
            if (image == null)
            {
                return;
            }
            this.ClearDraw();
            image = null;
            mainView.Invalidate();
        }


        /// <summary>
        /// 保存图片
        /// </summary>
        public bool SaveImage()
        {
            if (image == null)
            {
                return false;
            }
            //打开保存文件对话框保存图片
            using (SaveFileDialog sfd = new SaveFileDialog())
            {
                sfd.Title = "保存图片到：";
                sfd.DefaultExt = "bmp";
                sfd.CheckPathExists = true;
                sfd.Filter = "BMP|*.bmp|PNG|*.png|JPG|*.jpg|JPEG|*.jpeg|TIFF|*.tiff|GIF|*.gif";
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        string extension = Path.GetExtension(sfd.FileName);
                        switch (extension.ToLower())
                        {
                            case ".bmp":
                                image.bmp.Save(sfd.FileName, ImageFormat.Bmp);
                                break;
                            case ".png":
                                image.bmp.Save(sfd.FileName, ImageFormat.Png);
                                break;
                            case ".jpg":
                            case ".jpeg":
                                image.bmp.Save(sfd.FileName, ImageFormat.Jpeg);
                                break;
                            case ".tiff":
                                image.bmp.Save(sfd.FileName, ImageFormat.Tiff);
                                break;
                            case ".gif":
                                image.bmp.Save(sfd.FileName, ImageFormat.Gif);
                                break;
                            default:

                                break;
                        }
                    }
                    catch (Exception ex)
                    {
                        return false;
                    }
                }
            }
            return true;
        }

        /// <summary>
        /// 保存图片
        /// </summary>
        /// <param name="dir">文件夹路径</param>
        /// <param name="name">文件名（带后缀）</param>
        /// <param name="quality">压缩质量：当文件后缀名为jpg或jpeg时自动启用 取值范围(最差)0-100(最优)</param>
        public void Save(string dir, string name, byte quality = 100)
        {
            string extension = Path.GetExtension(name);

            //如果图像不存在或文件后缀不合理直接返回
            if (image == null || extension == null || extension == string.Empty)
            {
                return;
            }
            //判断文件夹是否存在，如果不存在先创建文件夹
            Directory.CreateDirectory(dir);
            //组合保存全路径
            string fullPath = Path.Combine(dir, name);
            //将文件后缀名转小写
            extension = extension.Trim().ToLower();
            //判断文件后缀是否需要保存压缩
            if (extension.Equals(".jpg") || extension.Equals(".jpeg"))
            {
                // 获取 JPEG 编码器
                ImageCodecInfo jpegCodecInfo = GetEncoderInfo("image/jpeg");
                // 创建 EncoderParameters 对象，设置压缩质量
                EncoderParameters encoderParameters = new EncoderParameters(1);
                encoderParameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
                image.bmp.Save(fullPath, jpegCodecInfo, encoderParameters);
            }
            //不进行压缩
            else
            {
                image.bmp.Save(fullPath);
            }
        }

        /// <summary>
        /// 检索图像编码器与解码器
        /// </summary>
        /// <param name="mimeType">"image/jpeg"</param>
        /// <returns>ImageCodecInfo / None</returns>
        private ImageCodecInfo GetEncoderInfo(string mimeType)
        {
            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
            for (int i = 0; i < codecs.Length; i++)
            {
                if (codecs[i].MimeType == mimeType)
                {
                    return codecs[i];
                }
            }
            return null;
        }


        /// <summary>
        /// 鼠标在显示区域移动事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainView_MouseMove(object sender, MouseEventArgs e)
        {
            if (image == null) { return; }

            //记录鼠标基于mainView位置
            mousePoint = e.Location;

            //实时计算拖动图片后的鼠标位置并重绘
            if (mainView.Cursor == Cursors.Hand && e.Button == MouseButtons.Left && operatorMode == HAUM_DRAW_MODE.None)
            {
                int dx = e.X - startMovePosition.X;
                int dy = e.Y - startMovePosition.Y;
                if (Math.Abs(dx) > 1 || Math.Abs(dy) > 1)
                {
                    offset.X += dx;
                    offset.Y += dy;
                    startMovePosition = e.Location;
                    mainView.Invalidate();
                }
                
            }

            switch (operatorMode)
            {
                case HAUM_DRAW_MODE.Point:
                    DrawPoint(e);
                    mainView.Invalidate();
                    break;
                case HAUM_DRAW_MODE.Line:
                    DrawLine(e);
                    mainView.Invalidate();
                    break;
                case HAUM_DRAW_MODE.Rectangle:
                    DrawRectangle(e);
                    mainView.Invalidate();
                    break;
                case HAUM_DRAW_MODE.Circle:
                    DrawCircle(e);
                    mainView.Invalidate();
                    break;
                case HAUM_DRAW_MODE.RotateRect:
                    DrawRotateRect(e);
                    mainView.Invalidate();
                    break;
                case HAUM_DRAW_MODE.Polygon:
                    DrawPolygon(e);
                    mainView.Invalidate();
                    break;
            }
        }


        /// <summary>
        /// 判断坐标点是否在图片上方
        /// </summary>
        /// <param name="mouseLocation"></param>
        /// <returns></returns>
        private bool IsMouseOnImage(Point mouseLocation)
        {
            PointF imageLoca = ScreenTransImagePointF(mouseLocation);
            if (imageLoca.X >= 0 && imageLoca.X < image.bmp.Width && imageLoca.Y >= 0 && imageLoca.Y < image.bmp.Height)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        /// <summary>
        /// 鼠标滚轮滚动事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainView_MouseWheel(object sender, MouseEventArgs e)
        {
            if (image != null)
            {
                float zoomFactor = e.Delta > 0 ? 1.1f : 0.9f;
                float oldScale = scaleF;
                scaleF *= zoomFactor;

                // 限制缩放范围
                if (scaleF < 0.01f) scaleF = 0.01f;
                if (scaleF > 100.0f) scaleF = 100.0f;


                // 根据鼠标位置调整偏移量
                float dx = (float)e.X - offset.X;
                float dy = (float)e.Y - offset.Y;
                offset.X -= dx * (scaleF / oldScale - 1);
                offset.Y -= dy * (scaleF / oldScale - 1);

                mainView.Invalidate();
            }
        }


        /// <summary>
        /// 将控件坐标点转为图像坐标点
        /// </summary>
        /// <param name="screenPoint">一个控件坐标点</param>
        /// <returns>图像坐标</returns>
        private PointF ScreenTransImagePointF(Point screenPoint)
        {
            // 计算鼠标在原始图片上的相对位置
            float relativeX = (screenPoint.X - offset.X) / scaleF;
            float relativeY = (screenPoint.Y - offset.Y) / scaleF;

            return new PointF(relativeX, relativeY);
        }

        /// <summary>
        /// 将图像坐标点转为控件坐标点
        /// </summary>
        /// <param name="imagePoint">一个图像坐标点</param>
        /// <returns>控件坐标</returns>
        private Point ImageTransScreenPoint(Point imagePoint)
        {
            float relativeX = imagePoint.X * scaleF + offset.X;
            float relativeY = imagePoint.Y * scaleF + offset.Y;

            return new Point((int)relativeX, (int)relativeY);
        }

        /// <summary>
        /// 将图像坐标点转为控件坐标点
        /// </summary>
        /// <param name="imagePoint">一个图像坐标点</param>
        /// <returns>控件坐标</returns>
        private PointF ImageTransScreenPointF(PointF imagePoint)
        {
            float relativeX = imagePoint.X * scaleF + offset.X;
            float relativeY = imagePoint.Y * scaleF + offset.Y;

            return new PointF(relativeX, relativeY);
        }

        /// <summary>
        /// 将图像坐标点集转为控件坐标点集
        /// </summary>
        /// <param name="imagePoint">一个图像坐标点</param>
        /// <returns>控件坐标</returns>
        private List<PointF> ImageTransScreenPointF(List<PointF> imagePoints)
        {
            List<PointF> ps = new List<PointF>();

            for (int i = 0; i < imagePoints.Count; i++)
            {
                PointF p = ImageTransScreenPointF(imagePoints[i]);
                ps.Add(p);
            }
            return ps;
        }

        /// <summary>
        /// 绘制点
        /// </summary>
        /// <param name="e"></param>
        private void PaintPoint(PaintEventArgs e)
        {
            using (Pen pen = new Pen(haumPoint.penColor, haumPoint.penSize))
            {
                PointF controlPoint = ImageTransScreenPointF(haumPoint.point);
                //float length = 5 * scaleF;
                float length = 10;
                // 绘制垂直的线（中心点上下各 5 像素）
                e.Graphics.DrawLine(pen, controlPoint.X, controlPoint.Y - length, controlPoint.X, controlPoint.Y + length);
                // 绘制水平的线（中心点左右各 5 像素）
                e.Graphics.DrawLine(pen, controlPoint.X - length, controlPoint.Y, controlPoint.X + length, controlPoint.Y);
            }
        }

        /// <summary>
        /// 绘制线
        /// </summary>
        /// <param name="e"></param>
        private void PaintLine(PaintEventArgs e)
        {
            using (Pen pen = new Pen(haumLine.penColor, haumLine.penSize))
            {
                PointF lineStart = ImageTransScreenPointF(haumLine.startPoint);
                PointF lineEnd = ImageTransScreenPointF(haumLine.endPoint);
                e.Graphics.DrawLine(pen, lineStart, lineEnd);

                // 箭头长度
                float arrowLength = 10 * haumLine.penSize;
                // 箭头角度（V 型开口角度）
                float arrowAngle = 30;
                // 箭头朝向角度（相对于水平向右为 0 度）
                float orientationAngle = haumLine.GetRotate();

                // 将角度转换为弧度
                float arrowAngleRadians = arrowAngle * (float)Math.PI / 180;
                float orientationAngleRadians = orientationAngle * (float)Math.PI / 180;

                // 尖角点位置
                PointF center = ImageTransScreenPointF(haumLine.GetCenter());
                PointF tipPoint = center;
                // 计算 V 型箭头的另外两个点
                float halfAngle = arrowAngleRadians / 2;
                PointF point1 = new PointF(
                    tipPoint.X - arrowLength * (float)Math.Cos(orientationAngleRadians - halfAngle),
                    tipPoint.Y - arrowLength * (float)Math.Sin(orientationAngleRadians - halfAngle)
                );
                PointF point2 = new PointF(
                    tipPoint.X - arrowLength * (float)Math.Cos(orientationAngleRadians + halfAngle),
                    tipPoint.Y - arrowLength * (float)Math.Sin(orientationAngleRadians + halfAngle)
                );

                //绘制尖角两条线形成指向箭头
                e.Graphics.DrawLine(pen, tipPoint, point1);
                e.Graphics.DrawLine(pen, tipPoint, point2);
            }

            using (Brush selectPen = new SolidBrush(haumLine.isSelect ? haumLine.selectColor : haumLine.penColor))
            {
                //绘制起点中点终点
                PointF start = ImageTransScreenPointF(haumLine.startPoint);
                PointF center = ImageTransScreenPointF(haumLine.GetCenter());
                PointF end = ImageTransScreenPointF(haumLine.endPoint);
                //起点
                e.Graphics.FillEllipse(selectPen, start.X - haumLine.penSize, start.Y - haumLine.penSize, haumLine.penSize * 2, haumLine.penSize * 2);
                //中点
                e.Graphics.FillEllipse(selectPen, center.X - haumLine.penSize, center.Y - haumLine.penSize, haumLine.penSize * 2, haumLine.penSize * 2);
                //终点
                e.Graphics.FillEllipse(selectPen, end.X - haumLine.penSize, end.Y - haumLine.penSize, haumLine.penSize * 2, haumLine.penSize * 2);

            }
        }

        /// <summary>
        /// 绘制矩形
        /// </summary>
        /// <param name="e"></param>
        private void PaintRectangle(PaintEventArgs e)
        {
            using (Pen pen = new Pen(haumRectangle.penColor, haumRectangle.penSize))
            {
                //获取圆心像素坐标 转换成控件坐标
                PointF center = ImageTransScreenPointF(haumRectangle.GetCenter());
                //根据中心坐标拟合两条垂直线
                // 绘制垂直的线（中心点上下各 3 像素）
                e.Graphics.DrawLine(pen, center.X, center.Y - 5, center.X, center.Y + 5);
                // 绘制水平的线（中心点左右各 3 像素）
                e.Graphics.DrawLine(pen, center.X - 5, center.Y, center.X + 5, center.Y);

                PointF rectTlLoca = ImageTransScreenPointF(haumRectangle.GetTL());
                PointF rectBrLoca = ImageTransScreenPointF(haumRectangle.GetBR());
                e.Graphics.DrawRectangle(pen, rectTlLoca.X, rectTlLoca.Y, rectBrLoca.X - rectTlLoca.X, rectBrLoca.Y - rectTlLoca.Y);
            }
            using (Brush selectPen = new SolidBrush(haumRectangle.isSelect ? haumRectangle.selectColor : haumRectangle.penColor))
            {
                PointF br = ImageTransScreenPointF(haumRectangle.GetBR());
                e.Graphics.FillEllipse(selectPen, br.X - haumRectangle.penSize, br.Y - haumRectangle.penSize, haumRectangle.penSize * 2, haumRectangle.penSize * 2);
            }
        }

        /// <summary>
        /// 绘制圆
        /// </summary>
        /// <param name="e"></param>
        private void PaintCircle(PaintEventArgs e)
        {
            using (Pen pen = new Pen(haumCircle.penColor, haumCircle.penSize))
            {
                //绘制圆心小十字
                //获取圆心像素坐标 转换成控件坐标
                PointF center = ImageTransScreenPointF(haumCircle.center);
                //根据中心坐标拟合两条垂直线
                // 绘制垂直的线（中心点上下各 3 像素）
                e.Graphics.DrawLine(pen, center.X, center.Y - 5, center.X, center.Y + 5);
                // 绘制水平的线（中心点左右各 3 像素）
                e.Graphics.DrawLine(pen, center.X - 5, center.Y, center.X + 5, center.Y);
                //圆的中心坐标转控件坐标
                PointF rectTL = ImageTransScreenPointF(haumCircle.GetRectTL());
                PointF rectBR = ImageTransScreenPointF(haumCircle.GetRectBR());
                SizeF size = new SizeF(rectBR.X - rectTL.X, rectBR.Y - rectTL.Y);
                e.Graphics.DrawEllipse(pen, new RectangleF(rectTL, size));
            }

            using (Brush selectPen = new SolidBrush(haumCircle.isSelect ? haumCircle.selectColor : haumCircle.penColor))
            {
                PointF rightPoint = ImageTransScreenPointF(haumCircle.GetScalePoint());
                //绘制拖动缩放点
                e.Graphics.FillEllipse(selectPen, rightPoint.X - haumCircle.penSize, rightPoint.Y - haumCircle.penSize, haumCircle.penSize * 2, haumCircle.penSize * 2);
            }
        }

        /// <summary>
        /// 绘制旋转矩形
        /// </summary>
        /// <param name="e"></param>
        private void PaintRotateRect(PaintEventArgs e)
        {
            using (Pen pen = new Pen(haumRotateRect.penColor, haumRotateRect.penSize))
            {
                //绘制矩形
                PointF[] corners = haumRotateRect.GetCorners();
                List<PointF> cornersScr = new List<PointF>();
                for (int i = 0; i < corners.Length; i++)
                {
                    cornersScr.Add(ImageTransScreenPointF(corners[i]));
                }
                e.Graphics.DrawPolygon(pen, cornersScr.ToArray());

                //绘制圆心小十字
                //获取圆心像素坐标 转换成控件坐标
                PointF center = ImageTransScreenPointF(haumRotateRect.center);
                //根据中心坐标拟合两条垂直线
                // 绘制垂直的线（中心点上下各 3 像素）
                e.Graphics.DrawLine(pen, center.X, center.Y - 5, center.X, center.Y + 5);
                // 绘制水平的线（中心点左右各 3 像素）
                e.Graphics.DrawLine(pen, center.X - 5, center.Y, center.X + 5, center.Y);
            }

            using (Brush selectPen = new SolidBrush(haumRotateRect.isSelect ? haumRotateRect.selectColor : haumRotateRect.penColor))
            {
                PointF tr = ImageTransScreenPointF(haumRotateRect.tr);
                e.Graphics.FillEllipse(selectPen, tr.X - haumRotateRect.penSize, tr.Y - haumRotateRect.penSize, haumRotateRect.penSize * 2, haumRotateRect.penSize * 2);

                PointF rc = ImageTransScreenPointF(haumRotateRect.GetRightCenter());
                e.Graphics.FillEllipse(selectPen, rc.X - haumRotateRect.penSize, rc.Y - haumRotateRect.penSize, haumRotateRect.penSize * 2, haumRotateRect.penSize * 2);

                PointF bc = ImageTransScreenPointF(haumRotateRect.GetBottomCenter());
                e.Graphics.FillEllipse(selectPen, bc.X - haumRotateRect.penSize, bc.Y - haumRotateRect.penSize, haumRotateRect.penSize * 2, haumRotateRect.penSize * 2);
            }
        }

        /// <summary>
        /// 绘制多边形
        /// </summary>
        /// <param name="e"></param>
        private void PaintPolygon(PaintEventArgs e)
        {
            if (haumPolygon.polygonPath.Count == 0)
            {
                return;
            }

            //绘制路径
            List<PointF> ps = ImageTransScreenPointF(haumPolygon.polygonPath);
            //连接线
            using (Pen pen = new Pen(haumPolygon.penColor, haumPolygon.penSize))
            {

                if (haumPolygon.polygonPath.Count >= 2)
                {
                    e.Graphics.DrawLines(pen, ps.ToArray());
                }

                //绘制中心小十字
                //获取圆心像素坐标 转换成控件坐标
                PointF center = ImageTransScreenPointF(haumPolygon.GetCenter());
                //根据中心坐标拟合两条垂直线
                // 绘制垂直的线（中心点上下各 3 像素）
                e.Graphics.DrawLine(pen, center.X, center.Y - 5, center.X, center.Y + 5);
                // 绘制水平的线（中心点左右各 3 像素）
                e.Graphics.DrawLine(pen, center.X - 5, center.Y, center.X + 5, center.Y);

            }
            //路径点
            using (Brush selectPen = new SolidBrush(haumPolygon.isSelect ? haumPolygon.selectColor : haumPolygon.penColor))
            {
                foreach (PointF p in ps)
                {
                    //绘制拖动缩放点
                    e.Graphics.FillEllipse(selectPen, p.X - haumPolygon.penSize, p.Y - haumPolygon.penSize, haumPolygon.penSize * 2, haumPolygon.penSize * 2);
                }
            }

        }

        /// <summary>
        /// 控件重绘
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainView_Paint(object sender, PaintEventArgs e)
        {
            lock (bmpLock)
            {
                if (image != null)
                {
                    // 计算缩放后的图片大小
                    int newWidth = (int)(image.bmp.Width * scaleF);
                    int newHeight = (int)(image.bmp.Height * scaleF);

                    // 判断显示模式设置绘制质量
                    if (viewMode == HAUM_DISPALY_MODE.Pixel)
                    {
                        e.Graphics.SmoothingMode = SmoothingMode.None;
                        e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
                        e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
                    }
                    else
                    {
                        e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
                        e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
                        e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                    }

                    // 获取控件的工作区域
                    Rectangle clientArea = mainView.ClientRectangle;
                    // 设置绘制区域限制
                    e.Graphics.SetClip(clientArea);

                    // 绘制缩放后的图片
                    e.Graphics.DrawImage(image.bmp, offset.X, offset.Y, newWidth, newHeight);

                    //更新缩放率
                    toolStripSplitButton_scale.Text = $"{(scaleF * 100).ToString("0")}%";

                    if (haumPoint != null)
                    {
                        PaintPoint(e);
                    }

                    if (haumLine != null)
                    {
                        PaintLine(e);
                    }

                    if (haumCircle != null)
                    {
                        PaintCircle(e);
                    }

                    if (haumEllipse != null)
                    {

                    }

                    if (haumRectangle != null)
                    {
                        PaintRectangle(e);
                    }

                    if (haumRotateRect != null)
                    {
                        PaintRotateRect(e);
                    }

                    if (haumPolygon != null)
                    {
                        PaintPolygon(e);
                    }
                }
            }
        }

        /// <summary>
        /// 绘制区域鼠标按下事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainView_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left && mainView.Cursor == Cursors.Hand)
            {
                startMovePosition = e.Location;
            }

            if (e.Button == MouseButtons.Right && operatorMode == HAUM_DRAW_MODE.None && operatorStatus == HAUM_DRAW_STATUS.Done)
            {
                contextMenuStrip_menu.Show(mainView, e.Location);
            }

            switch (operatorMode)
            {
                case HAUM_DRAW_MODE.Point:
                    DrawPoint(e);
                    break;
                case HAUM_DRAW_MODE.Line:
                    DrawLine(e);
                    break;
                case HAUM_DRAW_MODE.Rectangle:
                    DrawRectangle(e);
                    break;
                case HAUM_DRAW_MODE.RotateRect:
                    DrawRotateRect(e);
                    break;
                case HAUM_DRAW_MODE.Circle:
                    DrawCircle(e);
                    break;
                case HAUM_DRAW_MODE.Polygon:
                    DrawPolygon(e);
                    break;
            }

            mainView.Invalidate();

        }

        /// <summary>
        /// 判断是否能被选中
        /// </summary>
        /// <param name="center">中心点</param>
        /// <param name="mouse">鼠标点</param>
        /// <param name="relative">鼠标点与中心点距离 容错距离</param>
        /// <returns></returns>
        private bool IsCanSelect(PointF center, Point mouse, float relative)
        {

            PointF screenCenter = ImageTransScreenPointF(center);

            if (Math.Abs(mouse.X - screenCenter.X) <= relative && Math.Abs(mouse.Y - screenCenter.Y) <= relative)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 快捷菜单项被点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void contextMenuStrip_menu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            this.contextMenuStrip_menu.Close();

            string clickedItemText = e.ClickedItem.Text;

            switch (clickedItemText)
            {
                case "导入图像":
                    this.ImportImage();
                    break;
                case "自适应":
                    this.Fit();
                    break;
                case "水平翻转":
                    this.FlipX();
                    break;
                case "垂直翻转":
                    this.FlipY();
                    break;
                case "顺时针旋转":
                    this.RightRotate();
                    break;
                case "逆时针旋转":
                    this.LeftRotate();
                    break;
                case "恢复":
                    this.Restore();
                    break;
                case "像素级":
                    viewMode = HAUM_DISPALY_MODE.Pixel;
                    mainView.Invalidate();
                    break;
                case "高质量":
                    viewMode = HAUM_DISPALY_MODE.HeighQuality;
                    mainView.Invalidate();
                    break;
                case "Point":
                    StartDrawPoint();
                    break;
                case "Line":
                    StartDrawLine();
                    break;
                case "Rectangle":
                    StartDrawRectangle();
                    break;
                case "RotateRect":
                    StartDrawRotateRect();
                    break;
                case "Circle":
                    StartDrawCircle();
                    break;
                case "Elipse":
                    break;
                case "Polygon":
                    StartDrawPolygon();
                    break;
                case "1":
                    penSize = 1;
                    break;
                case "2":
                    penSize = 2;
                    break;
                case "3":
                    penSize = 3;
                    break;
                case "4":
                    penSize = 4;
                    break;
                case "5":
                    penSize = 5;
                    break;
                case "Black":
                    penColor = Color.Black;
                    break;
                case "White":
                    penColor = Color.White;
                    break;
                case "Red":
                    penColor = Color.Red;
                    break;
                case "Green":
                    penColor = Color.Green;
                    break;
                case "Blue":
                    penColor = Color.Blue;
                    break;
                case "Yellow":
                    penColor = Color.Yellow;
                    break;
                case "清除图形":
                    this.ClearDraw();
                    break;
                case "移除图像":
                    this.RemoveImage();
                    break;
                case "保存图像":
                    this.SaveImage();
                    break;
                case "属性":
                    if (imageInfo == null || imageInfo.IsDisposed)
                    {
                        imageInfo = new HaumImageInfo(image, Control.MousePosition);
                    }
                    imageInfo.Show();
                    break;
                default:

                    break;
            }
        }

        /// <summary>
        /// 图像显示控件调整大小事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainView_Resize(object sender, EventArgs e)
        {
            if (image != null)
            {
                Fit();
            }
        }


        #region 操作封装

        /// <summary>
        /// 清空绘制图形
        /// </summary>
        public void ClearDraw()
        {
            if (operatorMode == HAUM_DRAW_MODE.None && operatorStatus == HAUM_DRAW_STATUS.Done)
            {
                haumPoint = null;
                haumLine = null;
                haumRectangle = null;
                haumRotateRect = null;
                haumCircle = null;
                haumPolygon = null;
                mainView.Invalidate();
            }
        }

        /// <summary>
        /// 开始绘制点
        /// </summary>
        public void StartDrawPoint()
        {
            if (image != null)
            {
                haumPoint = new HaumPoint();
                haumPoint.penColor = penColor;
                haumPoint.penSize = penSize;
                operatorMode = HAUM_DRAW_MODE.Point;
                operatorStatus = HAUM_DRAW_STATUS.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        /// <summary>
        /// 绘制点过程
        /// </summary>
        /// <param name="e"></param>
        private void DrawPoint(MouseEventArgs e)
        {
            switch (operatorStatus)
            {
                case HAUM_DRAW_STATUS.Start:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        haumPoint.point = ScreenTransImagePointF(e.Location);
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
                case HAUM_DRAW_STATUS.Finish:
                    //更新点的位置
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        haumPoint.point = ScreenTransImagePointF(e.Location);
                    }
                    break;
            }
        }

        /// <summary>
        /// 开始绘制线
        /// </summary>
        public void StartDrawLine()
        {
            if (image != null)
            {
                haumLine = new HaumLine();
                haumLine.penColor = penColor;
                haumLine.penSize = penSize;
                operatorMode = HAUM_DRAW_MODE.Line;
                operatorStatus = HAUM_DRAW_STATUS.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        /// <summary>
        /// 绘制线过程
        /// </summary>
        /// <param name="e"></param>
        private void DrawLine(MouseEventArgs e)
        {
            switch (operatorStatus)
            {

                case HAUM_DRAW_STATUS.Start:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        haumLine.startPoint = ScreenTransImagePointF(e.Location);
                        haumLine.endPoint = ScreenTransImagePointF(e.Location);
                        operatorStatus = HAUM_DRAW_STATUS.Drawing;
                    }
                    break;
                case HAUM_DRAW_STATUS.Drawing:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        haumLine.endPoint = ScreenTransImagePointF(e.Location);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
                case HAUM_DRAW_STATUS.Finish:
                    if (IsMouseOnImage(e.Location) && IsCanSelect(haumLine.GetCenter(), e.Location, 5) ||
                        IsCanSelect(haumLine.startPoint, e.Location, 5) || IsCanSelect(haumLine.endPoint, e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeAll;
                        haumLine.isSelect = true;
                    }
                    else
                    {
                        mainView.Cursor = Cursors.Cross;
                        haumLine.isSelect = false;
                    }

                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(haumLine.GetCenter(), e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Moving;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(haumLine.startPoint, e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.StartDraging;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(haumLine.endPoint, e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.EndDraging;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && !IsCanSelect(haumLine.GetCenter(), e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Start;
                    }
                    break;
                case HAUM_DRAW_STATUS.Moving:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        float relativeX = ScreenTransImagePointF(e.Location).X - haumLine.GetCenter().X;
                        float relativeY = ScreenTransImagePointF(e.Location).Y - haumLine.GetCenter().Y;
                        //更新坐标
                        haumLine.startPoint.X += relativeX;
                        haumLine.startPoint.Y += relativeY;

                        haumLine.endPoint.X += relativeX;
                        haumLine.endPoint.Y += relativeY;
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
                case HAUM_DRAW_STATUS.StartDraging:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新起点坐标
                        haumLine.startPoint = ScreenTransImagePointF(e.Location);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
                case HAUM_DRAW_STATUS.EndDraging:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新终点坐标
                        haumLine.endPoint = ScreenTransImagePointF(e.Location);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
            }
        }

        /// <summary>
        /// 开始绘制矩形
        /// </summary>
        public void StartDrawRectangle()
        {
            if (image != null)
            {
                haumRectangle = new HaumRectangle();
                haumRectangle.penColor = penColor;
                haumRectangle.penSize = penSize;
                operatorMode = HAUM_DRAW_MODE.Rectangle;
                operatorStatus = HAUM_DRAW_STATUS.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        /// <summary>
        /// 绘制矩形过程
        /// </summary>
        /// <param name="e"></param>
        private void DrawRectangle(MouseEventArgs e)
        {
            switch (operatorStatus)
            {
                case HAUM_DRAW_STATUS.Start:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        haumRectangle.rect.Location = ScreenTransImagePointF(e.Location);
                        operatorStatus = HAUM_DRAW_STATUS.Drawing;
                    }
                    break;
                case HAUM_DRAW_STATUS.Drawing:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        PointF rbLoca = ScreenTransImagePointF(e.Location);
                        haumRectangle.rect.Width = Math.Abs(rbLoca.X - haumRectangle.rect.X);
                        haumRectangle.rect.Height = Math.Abs(rbLoca.Y - haumRectangle.rect.Y);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
                case HAUM_DRAW_STATUS.Finish:
                    //显示
                    if (IsMouseOnImage(e.Location) && IsCanSelect(haumRectangle.GetCenter(), e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeAll;
                        haumRectangle.isSelect = true;
                    }
                    else if (IsMouseOnImage(e.Location) && IsCanSelect(haumRectangle.GetBR(), e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeNWSE;
                        haumRectangle.isSelect = true;
                    }
                    else
                    {
                        mainView.Cursor = Cursors.Cross;
                        haumRectangle.isSelect = false;
                    }

                    //操作
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(haumRectangle.GetCenter(), e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Moving;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(haumRectangle.GetBR(), e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.BrDraging;
                    }
                    else if (e.Button == MouseButtons.Left && !IsCanSelect(haumRectangle.GetCenter(), e.Location, 5) && !IsCanSelect(haumRectangle.GetBR(), e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Start;
                    }
                    break;
                case HAUM_DRAW_STATUS.Moving:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新坐标
                        haumRectangle.rect.X = ScreenTransImagePointF(e.Location).X - haumRectangle.rect.Width / 2;
                        haumRectangle.rect.Y = ScreenTransImagePointF(e.Location).Y - haumRectangle.rect.Height / 2;
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;

                case HAUM_DRAW_STATUS.BrDraging:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新宽高
                        PointF mouse = ScreenTransImagePointF(e.Location);
                        haumRectangle.rect.Width = Math.Abs(mouse.X - haumRectangle.rect.X);
                        haumRectangle.rect.Height = Math.Abs(mouse.Y - haumRectangle.rect.Y);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
            }
        }

        /// <summary>
        /// 开始绘制椭圆
        /// </summary>
        public void StartDrawEllipse()
        {
            if (image != null)
            {
                haumEllipse = new HaumEllipse();
                haumEllipse.penColor = penColor;
                haumEllipse.penSize = penSize;
                operatorMode = HAUM_DRAW_MODE.Ellipse;
                operatorStatus = HAUM_DRAW_STATUS.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        /// <summary>
        /// 绘制椭圆过程
        /// </summary>
        /// <param name="e"></param>
        private void DrawEllipse(MouseEventArgs e)
        {
            switch (operatorStatus)
            {
                case HAUM_DRAW_STATUS.Start:

                    break;
                case HAUM_DRAW_STATUS.Drawing:

                    break;
                case HAUM_DRAW_STATUS.Finish:

                    break;
                case HAUM_DRAW_STATUS.Moving:

                    break;
            }
        }

        /// <summary>
        /// 开始绘制圆
        /// </summary>
        public void StartDrawCircle()
        {
            if (image != null)
            {
                haumCircle = new HaumCircle();
                haumCircle.penColor = penColor;
                haumCircle.penSize = penSize;
                operatorMode = HAUM_DRAW_MODE.Circle;
                operatorStatus = HAUM_DRAW_STATUS.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        /// <summary>
        /// 绘制圆过程
        /// </summary>
        /// <param name="e"></param>
        private void DrawCircle(MouseEventArgs e)
        {
            switch (operatorStatus)
            {

                case HAUM_DRAW_STATUS.Start:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        haumCircle.center = ScreenTransImagePointF(e.Location);
                        operatorStatus = HAUM_DRAW_STATUS.Drawing;
                    }
                    break;
                case HAUM_DRAW_STATUS.Drawing:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        PointF movePoint = ScreenTransImagePointF(e.Location);
                        //计算圆半径
                        haumCircle.radius = (float)Math.Sqrt(Math.Pow(Math.Abs(movePoint.X - haumCircle.center.X), 2) + Math.Pow(Math.Abs(movePoint.Y - haumCircle.center.Y), 2));
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
                case HAUM_DRAW_STATUS.Finish:
                    if (IsMouseOnImage(e.Location) && IsCanSelect(haumCircle.center, e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeAll;
                        haumCircle.isSelect = true;
                    }
                    else if (IsMouseOnImage(e.Location) && IsCanSelect(haumCircle.GetScalePoint(), e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeWE;
                        haumCircle.isSelect = true;
                    }
                    else
                    {
                        mainView.Cursor = Cursors.Cross;
                        haumCircle.isSelect = false;
                    }

                    //更新
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(haumCircle.center, e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Moving;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(haumCircle.GetScalePoint(), e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.ScaleDraging;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && !IsCanSelect(haumCircle.center, e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Start;
                    }
                    break;
                case HAUM_DRAW_STATUS.Moving:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新坐标
                        haumCircle.center = ScreenTransImagePointF(e.Location);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
                case HAUM_DRAW_STATUS.ScaleDraging:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新半径
                        haumCircle.radius = ScreenTransImagePointF(e.Location).X - haumCircle.center.X;
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
            }
        }

        /// <summary>
        /// 开始绘制旋转矩形
        /// </summary>
        public void StartDrawRotateRect()
        {
            if (image != null)
            {
                haumRotateRect = new HaumRotateRect();
                haumRotateRect.penColor = penColor;
                haumRotateRect.penSize = penSize;
                operatorMode = HAUM_DRAW_MODE.RotateRect;
                operatorStatus = HAUM_DRAW_STATUS.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        /// <summary>
        /// 绘制旋转矩形过程
        /// </summary>
        /// <param name="e"></param>
        private void DrawRotateRect(MouseEventArgs e)
        {
            switch (operatorStatus)
            {
                case HAUM_DRAW_STATUS.Start:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        haumRotateRect.center = ScreenTransImagePointF(e.Location);
                        operatorStatus = HAUM_DRAW_STATUS.Drawing;
                    }
                    break;
                case HAUM_DRAW_STATUS.Drawing:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        float w = ScreenTransImagePointF(e.Location).X - haumRotateRect.center.X;
                        float h = ScreenTransImagePointF(e.Location).Y - haumRotateRect.center.Y;
                        haumRotateRect.widthHalf = w;
                        haumRotateRect.heightHalf = h;
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
                case HAUM_DRAW_STATUS.Finish:
                    //显示
                    if (IsMouseOnImage(e.Location) && IsCanSelect(haumRotateRect.center, e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeAll;
                        haumRotateRect.isSelect = true;
                    }
                    else if (IsMouseOnImage(e.Location) && IsCanSelect(haumRotateRect.tr, e.Location, 10))
                    {
                        mainView.Cursor = rotateCursor;
                        haumRotateRect.isSelect = true;
                    }
                    else if (IsMouseOnImage(e.Location) && IsCanSelect(haumRotateRect.GetRightCenter(), e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeWE;
                        haumRotateRect.isSelect = true;
                    }
                    else if (IsMouseOnImage(e.Location) && IsCanSelect(haumRotateRect.GetBottomCenter(), e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeNS;
                        haumRotateRect.isSelect = true;
                    }
                    else
                    {
                        mainView.Cursor = Cursors.Cross;
                        haumRotateRect.isSelect = false;
                    }

                    //操作
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(haumRotateRect.center, e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Moving;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(haumRotateRect.tr, e.Location, 10))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Rotate;
                    }
                    else if (e.Button == MouseButtons.Left && IsCanSelect(haumRotateRect.GetRightCenter(), e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.RightDraging;
                    }
                    else if (e.Button == MouseButtons.Left && IsCanSelect(haumRotateRect.GetBottomCenter(), e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.BottomDraging;
                    }
                    else if (e.Button == MouseButtons.Left && !IsCanSelect(haumRotateRect.center, e.Location, 5) && !IsCanSelect(haumRotateRect.tr, e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Start;
                    }
                    break;
                case HAUM_DRAW_STATUS.Moving:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新坐标
                        PointF newP = ScreenTransImagePointF(e.Location);
                        haumRotateRect.MoveCenter(newP);
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
                case HAUM_DRAW_STATUS.Rotate:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //计算角度
                        PointF mouse = ScreenTransImagePointF(e.Location);
                        //计算中心与右上角角度
                        double r = ShapeTools.GetRotate(haumRotateRect.center, haumRotateRect.tr);
                        //计算鼠标与中心的角度
                        double mr = ShapeTools.GetRotate(haumRotateRect.center, mouse);
                        //角点旋转
                        haumRotateRect.Rotate(mr - r);

                        //获取左边与右边中点 计算矩形当前角度
                        haumRotateRect.rotate = ShapeTools.GetRotate(haumRotateRect.GetLeftCenter(), haumRotateRect.GetRightCenter());
                        if (Math.Abs(haumRotateRect.rotate) > 0 && Math.Abs(haumRotateRect.rotate) < 1)
                        {
                            haumRotateRect.Rotate(0 - haumRotateRect.rotate);
                            haumRotateRect.rotate += 0 - haumRotateRect.rotate;
                        }
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
                case HAUM_DRAW_STATUS.RightDraging:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        float w = ScreenTransImagePointF(e.Location).X - haumRotateRect.center.X;
                        haumRotateRect.widthHalf = w;
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
                case HAUM_DRAW_STATUS.BottomDraging:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        float h = ScreenTransImagePointF(e.Location).Y - haumRotateRect.center.Y;
                        haumRotateRect.heightHalf = h;
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
            }
        }


        /// <summary>
        /// 开始绘制多边形
        /// </summary>
        public void StartDrawPolygon()
        {
            if (image != null)
            {
                haumPolygon = new HaumPolygon();
                haumPolygon.penColor = penColor;
                haumPolygon.penSize = penSize;
                operatorMode = HAUM_DRAW_MODE.Polygon;
                operatorStatus = HAUM_DRAW_STATUS.Start;
                mainView.Cursor = Cursors.Cross;
            }
        }

        /// <summary>
        /// 绘制多边形过程
        /// </summary>
        /// <param name="e"></param>
        private void DrawPolygon(MouseEventArgs e)
        {
            switch (operatorStatus)
            {
                case HAUM_DRAW_STATUS.Start:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        if (haumPolygon.polygonPath.Count > 1)
                        {
                            haumPolygon.polygonPath.Clear();
                        }
                        //添加起点
                        haumPolygon.polygonPath.Add(ScreenTransImagePointF(e.Location));
                        operatorStatus = HAUM_DRAW_STATUS.Drawing;
                    }
                    break;
                case HAUM_DRAW_STATUS.Drawing:
                    if (IsMouseOnImage(e.Location) && IsCanSelect(haumPolygon.polygonPath[0], e.Location, 5))
                    {
                        mainView.Cursor = Cursors.Hand;
                    }
                    else
                    {
                        mainView.Cursor = Cursors.Cross;
                    }

                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && !IsCanSelect(haumPolygon.polygonPath[0], e.Location, 5))
                    {
                        //添加路径
                        haumPolygon.polygonPath.Add(ScreenTransImagePointF(e.Location));
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(haumPolygon.GetCenter(), e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Moving;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(haumPolygon.polygonPath[0], e.Location, 5))
                    {
                        PointF start = haumPolygon.polygonPath[0];
                        haumPolygon.polygonPath.Add(start);
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
                case HAUM_DRAW_STATUS.Finish:
                    if (IsMouseOnImage(e.Location) && IsCanSelect(haumPolygon.GetCenter(), e.Location, 5))
                    {
                        mainView.Cursor = Cursors.SizeAll;
                        haumPolygon.isSelect = true;
                    }
                    else
                    {
                        mainView.Cursor = Cursors.Cross;
                        haumPolygon.isSelect = false;
                    }

                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && IsCanSelect(haumPolygon.GetCenter(), e.Location, 10))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Moving;
                    }
                    else if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location) && !IsCanSelect(haumPolygon.polygonPath[0], e.Location, 5))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Start;
                    }
                    break;
                case HAUM_DRAW_STATUS.Moving:
                    if (e.Button == MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        //更新坐标
                        haumPolygon.ChangeAllPath(ScreenTransImagePointF(e.Location));
                    }
                    else if (e.Button != MouseButtons.Left && IsMouseOnImage(e.Location))
                    {
                        operatorStatus = HAUM_DRAW_STATUS.Finish;
                    }
                    break;
            }
        }


        /// <summary>
        /// 结束绘制
        /// </summary>
        public void DrawEnd()
        {
            operatorMode = HAUM_DRAW_MODE.None;
            operatorStatus = HAUM_DRAW_STATUS.Done;
            mainView.Cursor = Cursors.Hand;
        }

        /// <summary>
        /// 图像X水平翻转
        /// </summary>
        public void FlipX()
        {
            if (image != null)
            {
                image.bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
                this.Fit();
            }
        }

        /// <summary>
        /// 图形Y垂直翻转
        /// </summary>
        public void FlipY()
        {
            if (image != null)
            {
                image.bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
                this.Fit();
            }
        }

        /// <summary>
        /// 图像顺时针旋转
        /// </summary>
        public void LeftRotate()
        {
            if (image != null)
            {
                image.bmp.RotateFlip(RotateFlipType.Rotate270FlipNone);
                this.Fit();
            }
        }

        /// <summary>
        /// 图形逆时针旋转
        /// </summary>
        public void RightRotate()
        {
            if (image != null)
            {
                image.bmp.RotateFlip(RotateFlipType.Rotate90FlipNone);
                this.Fit();
            }
        }

        /// <summary>
        /// 旋转后恢复图像
        /// </summary>
        public void Restore()
        {
            this.Fit();
        }


        #endregion

        /// <summary>
        /// 菜单栏清空图形
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton_clear_Click(object sender, EventArgs e)
        {
            this.ClearDraw();
        }

        /// <summary>
        /// 鼠标样式切换到箭头
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void toolStripButton_arrow_Click(object sender, EventArgs e)
        {
            if (operatorMode == HAUM_DRAW_MODE.None)
            {
                mainView.Cursor = Cursors.Arrow;
            }
        }

        /// <summary>
        /// 鼠标样式切换到抓手
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void toolStripButton_hand_Click(object sender, EventArgs e)
        {
            if (operatorMode == HAUM_DRAW_MODE.None)
            {
                mainView.Cursor = Cursors.Hand;
            }
        }

        /// <summary>
        /// 自适应显示
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton_fit_Click(object sender, EventArgs e)
        {
            this.Fit();
        }

        /// <summary>
        /// 缩放选项点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripSplitButton_scale_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (image == null) { return; }

            float oldScale = scaleF;

            switch (e.ClickedItem.Text)
            {
                case "50%":
                    scaleF = 0.5f;
                    break;
                case "100%":
                    scaleF = 1f;
                    break;
                case "150%":
                    scaleF = 1.5f;
                    break;
                case "200%":
                    scaleF = 2f;
                    break;
            }

            float dx = mainView.Width / 2 - offset.X;
            float dy = mainView.Height / 2 - offset.Y;
            offset.X -= dx * (scaleF / oldScale - 1);
            offset.Y -= dy * (scaleF / oldScale - 1);

            mainView.Invalidate();
        }

        /// <summary>
        /// 菜单栏顺时针旋转
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton_leftRotate_Click(object sender, EventArgs e)
        {
            LeftRotate();
        }
        /// <summary>
        /// 菜单栏逆时针旋转
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton_rightRotate_Click(object sender, EventArgs e)
        {
            RightRotate();
        }


        private void toolStripMenuItem_point_Click(object sender, EventArgs e)
        {
            StartDrawPoint();
        }

        private void toolStripMenuItem_line_Click(object sender, EventArgs e)
        {
            StartDrawLine();
        }

        private void toolStripMenuItem_rectangle_Click(object sender, EventArgs e)
        {
            StartDrawRectangle();
        }

        private void toolStripMenuItem_circle_Click(object sender, EventArgs e)
        {
            StartDrawCircle();
        }

        /// <summary>
        /// 绘制区域控件鼠标点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainView_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right && operatorStatus != HAUM_DRAW_STATUS.Done && operatorStatus == HAUM_DRAW_STATUS.Finish)
            {
                switch (operatorMode)
                {
                    case HAUM_DRAW_MODE.Point:
                        haumPoint.isSelect = false;
                        break;
                    case HAUM_DRAW_MODE.Line:
                        haumLine.isSelect = false;
                        break;
                    case HAUM_DRAW_MODE.Circle:
                        haumCircle.isSelect = false;
                        break;
                    case HAUM_DRAW_MODE.Rectangle:
                        haumRectangle.isSelect = false;
                        break;
                    case HAUM_DRAW_MODE.RotateRect:
                        haumRotateRect.isSelect = false;
                        break;
                    case HAUM_DRAW_MODE.Polygon:
                        haumPolygon.isSelect = false;
                        break;
                }
                //结束绘制
                this.DrawEnd();

            }
        }

        private void toolStripMenuItem_polygon_Click(object sender, EventArgs e)
        {
            StartDrawPolygon();
        }

        private void toolStripMenuItem_rotateRect_Click(object sender, EventArgs e)
        {
            StartDrawRotateRect();
        }

        /// <summary>
        /// 获取绘制的点
        /// </summary>
        /// <returns></returns>
        public HaumPoint GetDrawPoint()
        {
            return haumPoint;
        }
        /// <summary>
        /// 获取绘制的线
        /// </summary>
        /// <returns></returns>
        public HaumLine GetDrawLine()
        {
            return haumLine;
        }
        /// <summary>
        /// 获取绘制的圆
        /// </summary>
        /// <returns></returns>
        public HaumCircle GetDrawCircle()
        {
            return haumCircle;
        }
        /// <summary>
        /// 获取绘制的矩形
        /// </summary>
        /// <returns></returns>
        public HaumRectangle GetDrawRectangle()
        {
            return haumRectangle;
        }
        /// <summary>
        /// 获取绘制的旋转矩形
        /// </summary>
        /// <returns></returns>
        public HaumRotateRect GetDrawRotateRect()
        {
            return haumRotateRect;
        }
        /// <summary>
        /// 获取绘制的多边形
        /// </summary>
        /// <returns></returns>
        public HaumPolygon GetDrawPolygon()
        {
            return haumPolygon;
        }

        /// <summary>
        /// 获取一个指定类型的绘制图形
        /// </summary>
        /// <param name="type">图形类型</param>
        /// <returns>指定绘制类型的图形对象</returns>
        public Object GetRequireGraphic(Type type) {
            if (type == typeof(HaumPoint))
            {
                return haumPoint;
            }
            else if (type == typeof(HaumLine))
            {
                return haumLine;
            }
            else if (type == typeof(HaumCircle))
            {
                return haumCircle;
            }
            else if (type == typeof(HaumEllipse))
            {
                return haumEllipse;
            }
            else if (type == typeof(HaumRectangle))
            {
                return haumRectangle;
            }
            else if (type == typeof(HaumRotateRect))
            {
                return haumRotateRect;
            }
            else if (type == typeof(HaumPolygon))
            {
                return haumPolygon;
            }
            else {
                return null;
            }
        }

        /// <summary>
        /// 绘制区域控件尺寸改变事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainView_SizeChanged(object sender, EventArgs e)
        {
            this.Fit();
        }
        /// <summary>
        /// 控件加载事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HaumDisplayWindow_Load(object sender, EventArgs e)
        {
            listenKeys = new Thread(ListenKeys);
            listenKeys.Start();
        }

        private void mainView_MouseLeave(object sender, EventArgs e)
        {
            isInView = false;
        }

        private void mainView_MouseEnter(object sender, EventArgs e)
        {
            isInView = true;
        }

        private void HaumDisplayWindow_DragDrop(object sender, DragEventArgs e)
        {
            try
            {
                // 获取拖放的文件
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

                if (files.Length > 0)
                {
                    // 获取第一个文件路径
                    string filePath = files[0];

                    // 检查文件是否为图片
                    if (IsImageFile(filePath))
                    {
                        // 显示图片
                        this.LoadImage(filePath);
                    }
                    else
                    {
                        MessageBox.Show("请拖放有效的图片文件！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("处理图片时出错: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void HaumDisplayWindow_DragEnter(object sender, DragEventArgs e)
        {
            // 检查拖放的数据是否包含文件
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                // 获取拖放的文件
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

                // 检查第一个文件是否为图片文件
                if (files.Length == 1 && IsImageFile(files[0]))
                {
                    // 允许复制操作
                    e.Effect = DragDropEffects.Copy;
                }
                else {
                    // 不允许拖放
                    e.Effect = DragDropEffects.None;
                }
            }
            else
            {
                // 不允许拖放
                e.Effect = DragDropEffects.None;
            }
        }

        private bool IsImageFile(string filePath)
        {
            // 获取文件扩展名并转换为小写
            string extension = Path.GetExtension(filePath).ToLower();

            // 检查文件扩展名是否为常见的图片格式
            switch (extension.ToLower())
            {
                case ".jpg":
                case ".jpeg":
                case ".png":
                case ".bmp":
                case ".gif":
                case ".tiff":
                    return true;
                default:
                    return false;
            }
        }

    }
}
